package com.rtsapp.server.logger.async;

import com.rtsapp.server.logger.spi.LogLog;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 异步日志线程
 */
public class AsyncLoggerThread implements Runnable{

    /**
     * 默认的轮询一次周期时间: 100毫秒, 改时间运行时调成最佳值
     */
    private static final long DEFAULT_LOGGER_PERIOD = 100;
    private static final int DEFAULT_MAX_LOGGER_PER_THREAD = 64;

    private final AtomicInteger loggerSize = new AtomicInteger( 0 );

    private final IAsyncLogger[] loggers= new IAsyncLogger[ DEFAULT_MAX_LOGGER_PER_THREAD ];

    private volatile boolean isShutdown = false;

    private final CountDownLatch countDownLatch;


    public AsyncLoggerThread(CountDownLatch countDownLatch) {
        this.countDownLatch = countDownLatch;
    }

    /**
     * 注册一个Logger给线程管理
     * @param logger
     * @throws AsyncLoggerTooMuchExecption
     */
    public void register( IAsyncLogger logger ) throws AsyncLoggerTooMuchExecption {
        int index = loggerSize.getAndIncrement();

        if( index < DEFAULT_MAX_LOGGER_PER_THREAD  ){
            loggers[ index ] = logger;
        }else{
            throw new AsyncLoggerTooMuchExecption();
        }
    }

    /**
     * 关闭线程
     */
    public void shutdown(){
        isShutdown = true;
    }

    @Override
    public void run() {

        while( true ){

            try{

                long startTime = System.currentTimeMillis();

                //处理所有日志
                int queueSize = loggerSize.get();
                long logSize = 0;
                for( int i = 0; i < queueSize; i++ ){
                    if( loggers[ i ] != null ){
                        logSize += loggers[ i ].doLogger( );
                    }
                }

                // 线程停止
                if( isShutdown && logSize == 0 ){
                    break;
                }

                long endTime = System.currentTimeMillis();
                long remaingTime = DEFAULT_LOGGER_PERIOD - ( endTime - startTime );
                if( remaingTime > 0 ){
                    Thread.sleep( remaingTime );
                }

            }catch ( InterruptedException ex ){
                LogLog.error("AsyncLoggerThread运行中发生中断", ex);
            }catch( Throwable ex ) {
                LogLog.error("AsyncLoggerThread运行中发生异常", ex);
            }
        }

        countDownLatch.countDown();

        LogLog.debug( "AsyncLoggerThread线程:" +  Thread.currentThread() + " 退出" );

    }

}
